前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket

# 基础调试 console

30 秒速记

  • console 是开发期的调试工具:log/info 写 stdout,error/warn/trace 写 stderr
  • 常用全家桶:log、error、dir(控制展开深度)、time/timeEnd(计时)、trace(打调用栈)、table、assert
  • new console.Console(stdout, stderr) 可以把输出导到文件或任意可写流
  • 写文件和管道时 console 可能是同步的,高频打印会拖慢服务;线上日志用 pino 这类结构化日志库
  • 别直接打 req、token、用户数据,对象太大还会刷屏、带出敏感字段

console 是 Node 里最顺手的调试工具,但它定位是「开发时看一眼」,不是生产日志方案。 它分两条输出通道:普通信息走标准输出,错误和警告走标准错误,这个区分在重定向和日志采集时很有用,比如 node app.js 2> err.log 就能只把错误存下来。除了 log,dir 看深层对象、time 测耗时、trace 查是谁调的这个函数,都是排查问题的利器。线上要的是带级别、时间戳、请求 ID 的 JSON 日志,那就交给专门的日志库。

理解「基础调试 console」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 module 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

console 在 Node 里其实是 Console 类的一个实例,绑定了 process.stdout 和 process.stderr 两个流。记住哪个方法写到哪个流,排查「日志去哪了」就很快:

方法 输出流 用途
console.log / console.info / console.debug stdout 普通信息
console.error / console.warn stderr 错误、警告
console.trace stderr 带调用栈的信息
console.dir stdout 按指定深度展开对象
console.table stdout 数组、对象以表格展示
console.time / console.timeEnd stdout 计时
// demo.js
console.log('normal');
console.error('oops');
console.table([{ a: 1, b: 2 }, { a: 3, b: 4 }]);
@前端进阶之旅: 代码已经复制到剪贴板
node demo.js 2>/dev/null
# 只看到 normal 和表格,oops 被丢掉了,因为它在 stderr
@前端进阶之旅: 代码已经复制到剪贴板

开发时 console 足够用;服务上线后,日志要能被检索和告警,至少需要时间、级别、请求 ID、事件名和上下文字段,这时候换成 pino、winston 之类的结构化日志库,输出 JSON 交给日志平台采集。

面试官追问

追问 1node app.js > out.log,为什么报错信息还是打在终端上?
参考回答

> 只重定向标准输出,console.error 走的是标准错误。要一起存就写 node app.js > out.log 2>&1。

追问 2高并发接口里每个请求打好几行 console.log,压测时 RT 明显变高,为什么?
参考回答

stdout 指向文件或管道时,写入可能是同步的,大量打印会占住主线程;而且 util.inspect 格式化大对象本身就耗 CPU。线上换 pino 这类异步、JSON 格式的日志库,调试日志按级别关掉。

追问 3想打印一个请求对象排查问题,console.log(req) 有什么风险?
参考回答

一是太大,IncomingMessage 上挂着 socket 等一堆内部对象,刷屏还看不清;二是会把 Cookie、Authorization 头这些敏感信息写进日志。挑需要的字段打:console.log({ url: req.url, method: req.method })。

追问 4进程最后一行 console.log('done') 打出来了,能说明任务成功了吗?
参考回答

不能,只说明代码跑到了那一行。看 echo $? 拿退出码,失败分支要 process.exitCode = 1,调度器和 CI 是按退出码判断成败的。

追问 5console.log 和 process.stdout.write 有啥区别?
参考回答

console.log 会用 util.format 格式化参数、支持 %s/%d/%o 占位符,并且自动加换行;process.stdout.write 原样写字符串,不加换行。做进度条这种需要覆盖同一行的输出就用后者配合 \r。

# 模块概览

30 秒速记

  • console 是全局对象,直接用;最常用的是 console.log() 和 console.error()
  • 两条通道:log → stdout,error → stderr,重定向和日志采集时能分开处理
  • Console 类可以 new 出自己的实例,把输出写到文件或任意可写流
  • 浏览器的 console 和 Node 的长得像,但 Node 版本质是往两个流里写字符串

console 模块就是 Node 自带的调试输出工具,全局可用,常用的就是 log 和 error 两个。 它和浏览器的 console 用法几乎一样,区别在于 Node 里输出最后是写到进程的标准输出和标准错误两个流里。log 和 error 看起来都是在终端打一行字,但走的是不同通道,部署时可以把错误单独重定向、单独告警。另外 console 本身是 Console 类的实例,你可以自己 new 一个,把调试信息写进文件,这在没有日志库的小脚本里很方便。

console模块提供了基础的调试功能。使用很简单,常用的API主要有 console.log()、console.error()。

此外,可以基于Console类,方便的扩展出自己的console实例,比如把调试信息打印到文件里,而部署输出在控制台上。

直接看例子。

面试官追问

追问 1console.log 和 console.error 在终端里看着一样,随便用行吗?
参考回答

不行。2> err.log 重定向、PM2 的 error_file、Docker 日志驱动都能区分这两条流,错误写成 log 就进不了错误日志,告警也抓不到。

追问 2小脚本想把调试信息写进文件,又不想装日志库,怎么做?
参考回答

const logger = new console.Console(fs.createWriteStream('./debug.log')),之后用 logger.log()。只传一个流时,error 也会写到这个流里。

追问 3PM2 跑的服务,console.error 的内容去哪了?
参考回答

PM2 默认把 stdout 和 stderr 分开存,在 ~/.pm2/logs/ 下的 xxx-out.log 和 xxx-error.log。用 pm2 logs 能同时看两边。

追问 4能不能把全局 console.log 改写一下,统一加时间戳?
参考回答

能,比如 const raw = console.log; console.log = (...a) => raw(new Date().toISOString(), ...a)。小项目临时这么干没问题,正经项目还是用日志库,改全局对象会影响所有依赖包的输出。

# 基础例子

30 秒速记

  • console.log 普通信息 → stdout;console.error 错误信息 → stderr
  • console.info 是 log 的别名,console.warn 是 error 的别名,Node 里输出没有区别
  • 多个参数用空格拼接;第一个参数里可以写占位符:%s 字符串、%d 数字、%j JSON、%o 对象
  • 占位符多出来的参数接在后面,不够的占位符原样输出

Node 里 console 的打印方法其实就两类:写标准输出的 log/info,写标准错误的 error/warn。 在 Node 里 info 和 log 完全一样,warn 和 error 完全一样,不像浏览器控制台会用颜色和级别区分,所以选哪个更多是代码语义问题。参数可以一个个传,console.log('user', name) 会用空格拼起来;也可以用占位符,console.log('user: %s, age: %d', name, age),底层都是 util.format 处理的。

无特殊说明,日志都是默认打印到控制台。最常用的是console.log()、console.error()两个方法。

  • console.log(msg):普通日志打印。
  • console.error(msg):错误日志打印。
  • console.info(msg):等同于console.log(msg)
  • console.warn(msg):等同于console.error(msg)

例子如下:

console.log('log: hello');
console.log('log: hello', 'chyingp');
console.log('log: hello %s', 'chyingp');

基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
      • 模块概览
      • 基础例子
      • 自定义stdout
      • 计时
      • 断言
      • 打印错误堆栈:console.trace(msg)
      • 深层打印
      • 相关链接
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket
完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

基础调试 console|Nodejs专题系列

# 基础调试 console

30 秒速记

  • console 是开发期的调试工具:log/info 写 stdout,error/warn/trace 写 stderr
  • 常用全家桶:log、error、dir(控制展开深度)、time/timeEnd(计时)、trace(打调用栈)、table、assert
  • new console.Console(stdout, stderr) 可以把输出导到文件或任意可写流
  • 写文件和管道时 console 可能是同步的,高频打印会拖慢服务;线上日志用 pino 这类结构化日志库
  • 别直接打 req、token、用户数据,对象太大还会刷屏、带出敏感字段

console 是 Node 里最顺手的调试工具,但它定位是「开发时看一眼」,不是生产日志方案。 它分两条输出通道:普通信息走标准输出,错误和警告走标准错误,这个区分在重定向和日志采集时很有用,比如 node app.js 2> err.log 就能只把错误存下来。除了 log,dir 看深层对象、time 测耗时、trace 查是谁调的这个函数,都是排查问题的利器。线上要的是带级别、时间戳、请求 ID 的 JSON 日志,那就交给专门的日志库。

理解「基础调试 console」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 module 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

console 在 Node 里其实是 Console 类的一个实例,绑定了 process.stdout 和 process.stderr 两个流。记住哪个方法写到哪个流,排查「日志去哪了」就很快:

方法 输出流 用途
console.log / console.info / console.debug stdout 普通信息
console.error / console.warn stderr 错误、警告
console.trace stderr 带调用栈的信息
console.dir stdout 按指定深度展开对象
console.table stdout 数组、对象以表格展示
console.time / console.timeEnd stdout 计时
// demo.js
console.log('normal');
console.error('oops');
console.table([{ a: 1, b: 2 }, { a: 3, b: 4 }]);
@前端进阶之旅: 代码已经复制到剪贴板
node demo.js 2>/dev/null
# 只看到 normal 和表格,oops 被丢掉了,因为它在 stderr
@前端进阶之旅: 代码已经复制到剪贴板

开发时 console 足够用;服务上线后,日志要能被检索和告警,至少需要时间、级别、请求 ID、事件名和上下文字段,这时候换成 pino、winston 之类的结构化日志库,输出 JSON 交给日志平台采集。

面试官追问

追问 1node app.js > out.log,为什么报错信息还是打在终端上?
参考回答

> 只重定向标准输出,console.error 走的是标准错误。要一起存就写 node app.js > out.log 2>&1。

追问 2高并发接口里每个请求打好几行 console.log,压测时 RT 明显变高,为什么?
参考回答

stdout 指向文件或管道时,写入可能是同步的,大量打印会占住主线程;而且 util.inspect 格式化大对象本身就耗 CPU。线上换 pino 这类异步、JSON 格式的日志库,调试日志按级别关掉。

追问 3想打印一个请求对象排查问题,console.log(req) 有什么风险?
参考回答

一是太大,IncomingMessage 上挂着 socket 等一堆内部对象,刷屏还看不清;二是会把 Cookie、Authorization 头这些敏感信息写进日志。挑需要的字段打:console.log({ url: req.url, method: req.method })。

追问 4进程最后一行 console.log('done') 打出来了,能说明任务成功了吗?
参考回答

不能,只说明代码跑到了那一行。看 echo $? 拿退出码,失败分支要 process.exitCode = 1,调度器和 CI 是按退出码判断成败的。

追问 5console.log 和 process.stdout.write 有啥区别?
参考回答

console.log 会用 util.format 格式化参数、支持 %s/%d/%o 占位符,并且自动加换行;process.stdout.write 原样写字符串,不加换行。做进度条这种需要覆盖同一行的输出就用后者配合 \r。

# 模块概览

30 秒速记

  • console 是全局对象,直接用;最常用的是 console.log() 和 console.error()
  • 两条通道:log → stdout,error → stderr,重定向和日志采集时能分开处理
  • Console 类可以 new 出自己的实例,把输出写到文件或任意可写流
  • 浏览器的 console 和 Node 的长得像,但 Node 版本质是往两个流里写字符串

console 模块就是 Node 自带的调试输出工具,全局可用,常用的就是 log 和 error 两个。 它和浏览器的 console 用法几乎一样,区别在于 Node 里输出最后是写到进程的标准输出和标准错误两个流里。log 和 error 看起来都是在终端打一行字,但走的是不同通道,部署时可以把错误单独重定向、单独告警。另外 console 本身是 Console 类的实例,你可以自己 new 一个,把调试信息写进文件,这在没有日志库的小脚本里很方便。

console模块提供了基础的调试功能。使用很简单,常用的API主要有 console.log()、console.error()。

此外,可以基于Console类,方便的扩展出自己的console实例,比如把调试信息打印到文件里,而部署输出在控制台上。

直接看例子。

面试官追问

追问 1console.log 和 console.error 在终端里看着一样,随便用行吗?
参考回答

不行。2> err.log 重定向、PM2 的 error_file、Docker 日志驱动都能区分这两条流,错误写成 log 就进不了错误日志,告警也抓不到。

追问 2小脚本想把调试信息写进文件,又不想装日志库,怎么做?
参考回答

const logger = new console.Console(fs.createWriteStream('./debug.log')),之后用 logger.log()。只传一个流时,error 也会写到这个流里。

追问 3PM2 跑的服务,console.error 的内容去哪了?
参考回答

PM2 默认把 stdout 和 stderr 分开存,在 ~/.pm2/logs/ 下的 xxx-out.log 和 xxx-error.log。用 pm2 logs 能同时看两边。

追问 4能不能把全局 console.log 改写一下,统一加时间戳?
参考回答

能,比如 const raw = console.log; console.log = (...a) => raw(new Date().toISOString(), ...a)。小项目临时这么干没问题,正经项目还是用日志库,改全局对象会影响所有依赖包的输出。

# 基础例子

30 秒速记

  • console.log 普通信息 → stdout;console.error 错误信息 → stderr
  • console.info 是 log 的别名,console.warn 是 error 的别名,Node 里输出没有区别
  • 多个参数用空格拼接;第一个参数里可以写占位符:%s 字符串、%d 数字、%j JSON、%o 对象
  • 占位符多出来的参数接在后面,不够的占位符原样输出

Node 里 console 的打印方法其实就两类:写标准输出的 log/info,写标准错误的 error/warn。 在 Node 里 info 和 log 完全一样,warn 和 error 完全一样,不像浏览器控制台会用颜色和级别区分,所以选哪个更多是代码语义问题。参数可以一个个传,console.log('user', name) 会用空格拼起来;也可以用占位符,console.log('user: %s, age: %d', name, age),底层都是 util.format 处理的。

无特殊说明,日志都是默认打印到控制台。最常用的是console.log()、console.error()两个方法。

  • console.log(msg):普通日志打印。
  • console.error(msg):错误日志打印。
  • console.info(msg):等同于console.log(msg)
  • console.warn(msg):等同于console.error(msg)

例子如下:

console.log('log: hello');
console.log('log: hello', 'chyingp');
console.log('log: hello %s', 'chyingp');

console.error('error: hello');
console.error('error: hello', 'chyingp');
console.error('error: hello %s', 'chyingp');

// 输出如下:
// log: hello
// log: hello chyingp
// log: hello chyingp
// error: hello
// error: hello chyingp
// error: hello chyingp
@前端进阶之旅: 代码已经复制到剪贴板

面试官追问

追问 1console.log('hello', 'tom') 和 console.log('hello %s', 'tom') 有区别吗?
参考回答

这个例子输出都是 hello tom。区别在于占位符能控制格式:console.log('%d', '42abc') 输出 NaN,console.log('%s', {a:1}) 会把对象格式化成字符串;直接传参数则用默认方式 inspect。

追问 2console.log('a %s %s', 'x') 输出什么?
参考回答

a x %s。占位符多了参数不够,剩下的原样打出来;反过来参数多了,就用空格接在后面。

追问 3只用 console.log,把错误也打进去,会损失什么?
参考回答

错误就混进了标准输出,2> 重定向、PM2 的错误日志、按流区分的告警全都抓不到它。错误分支就用 console.error。

追问 4线上只看到 error 那几行,log 的一行都没有,代码顺序被打乱了?
参考回答

不是,是日志采集只收了 stderr,或者 stdout 被重定向到了别处。先查进程的 stdout 去了哪(启动命令、PM2/Docker 配置),再用最小脚本两种都打一行验证。

追问 5团队规范里 warn 和 error 要不要都保留?
参考回答

在 Node 里它们输出完全一样,保留两个只是表达语义。如果后面要换成带级别的日志库,提前区分好 warn 和 error 方便迁移,这是保留它们唯一的实际价值。

# 自定义stdout

← 2.0 文件系统操作 fs3.2 本地调试远程服务器上的Node代码 →

fe